package common.util;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/** 公共日期时间操作工具类 */
public class DateTime {
	/** DateTimeFormat1 = "yyyy-MM-dd HH:mm:ss" */
	public static final String DateTimeFormat1 = "yyyy-MM-dd HH:mm:ss";

	/** DateTimeFormat2 = "yyyy-MM-dd HH:mm:ss:SSS" */
	public static final String DateTimeFormat2 = "yyyy-MM-dd HH:mm:ss:SSS";

	/** DateFormat1 = "yyyy-MM-dd" */
	public static final String DateFormat1 = "yyyy-MM-dd";

	/** DateFormat2 = "yyyy/MM/dd" */
	public static final String DateFormat2 = "yyyy/MM/dd";

	/** DateFormat3 = "yyyy.MM.dd" */
	public static final String DateFormat3 = "yyyy.MM.dd";

	/** TimeFormat1 = "HH:mm:ss" */
	public static final String TimeFormat1 = "HH:mm:ss";

	/** TimeFormat2 = "HH:mm:ss:SSS" */
	public static final String TimeFormat2 = "HH:mm:ss:SSS";

	/** _HH : 一小时的毫秒数 60 * 60 * 1000 */
	public static final int _HH = 60 * 60 * 1000;

	/** _MM : 一分钟的毫秒数 60 * 1000 */
	public static final int _MM = 60 * 1000;

	/** _SS : 一秒的毫秒数 1000 */
	public static final int _SS = 1000;

	/**
	 * @return 返回文本信息的日期对应的格林威治标准时间（1970年1月1日00:00:00.000）的偏移量,单位是毫秒。 1秒=1000毫秒。
	 * @param format
	 *            "yyyy-MM-dd HH:mm:ss:SSS"或"yyyy-MM-dd HH:mm:ss"。
	 */
	public static long dateTimeParse(String datetime, String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		try {
			Date date = sdf.parse(datetime);
			return date.getTime();
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		}
		return 0;
	}

	/**
	 * @return 返回测试时间是否在beginTime和endTime之间，如果在返回true，不在返回false。
	 * @param beginTime
	 *            开始时间。格式为："yyyy-MM-dd HH:mm:ss:SSS"或者"yyyy-MM-dd HH:mm:ss"。
	 * @param endTime
	 *            结束时间。格式同上。
	 * @param testTime
	 *            被测试的时间。格式同上。
	 * @param timeFormat
	 *            共同的格式为："yyyy-MM-dd HH:mm:ss:SSS"或"yyyy-MM-dd
	 *            HH:mm:ss"，请使用本类中提供的类型 。
	 */
	public static boolean isInTwoTime(String beginTime, String endTime,
			String testTime, String timeFormat) {
		long begin = DateTime.dateTimeParse(beginTime, timeFormat);
		long end = DateTime.dateTimeParse(endTime, timeFormat);
		long test = DateTime.dateTimeParse(testTime, timeFormat);
		if (test > begin && test < end) {
			return true;
		}
		return false;
	}

	/**
	 * @param dateFormat
	 *            请使用本类提供的类型。格式："yyyy-MM-dd"或"yyyy/MM/dd"或"yyyy.MM.dd" 。
	 * @return 返回指定格式的当前日期
	 */
	public static String currentDate(String dateFormat) {
		Date d = new java.util.Date();
		SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
		return sdf.format(d);
	}

	/**
	 * @param timeFormat
	 *            请使用本类提供的类型。格式："HH:mm:ss"或"HH:mm:ss:SSS" 。
	 * @return 返回指定格式的当前时间
	 */
	public static String currentTime(String timeFormat) {
		Date d = new java.util.Date();
		SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
		return sdf.format(d);
	}

	/**
	 * @param format
	 *            请使用本类提供的类型。格式："yyyy-MM-dd HH:mm:ss:SSS"或"yyyy-MM-dd HH:mm:ss"。
	 * @return 返回指定格式的当前日期时间
	 */
	public static String currentDateTime(String format) {
		Date d = new java.util.Date();
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		return sdf.format(d);
	}

	/** 获得当前时间,格式为："yyyy-MM-dd HH:mm:ss.SSS" */
	public static String currentDateTime() {
		return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(Calendar
				.getInstance().getTime());
	}

	/**
	 * @return 返回当前系统时间的格林威治毫秒时。
	 * @param format
	 *            指定返回的值精确到秒还是毫秒。请使用本类提供的类型。格式："yyyy-MM-dd HH:mm:ss:SSS"精确到毫秒 或
	 *            "yyyy-MM-dd HH:mm:ss"精确到秒。
	 */
	public static long currentDateTimeGreenwich(String format) {
		Calendar rightNow = Calendar.getInstance();
		SimpleDateFormat sdf = new SimpleDateFormat(format);
		String sysDatetime = sdf.format(rightNow.getTime());
		return DateTime.dateTimeParse(sysDatetime, format);
	}

	/**
	 * 返回以毫秒为单位的当前时间。注意，当返回值的时间单位是毫秒时，值的粒度取决于底层操作系统，并且粒度可能更大。
	 * 例如，许多操作系统以几十毫秒为单位测量时间。 请参阅 Date 类的描述，了解可能发生在“计算机时间”和协调世界时
	 * （UTC）之间的细微差异的讨论。 返回： 当前时间与协调世界时 1970 年 1 月 1 日午夜之间的时间差（以毫秒为单 位测量）。
	 * 
	 * @see Date
	 */
	public static long currentTimeMillis() {
		return System.currentTimeMillis();
	}

	/**
	 * 返回最准确的可用系统计时器的当前值，以毫微秒为单位。此方法只能用于测量已过的时间，与系统或钟表时间的其他任何时间概念无关。
	 * 返回值表示从某一固定但任意的时间算起的毫微秒数（或许从以后算起，所以该值可能为负）。此方法提供毫微秒的精度，但不是必要的毫
	 * 微秒的准确度。它对于值的更改频率没有作出保证。在取值范围大于约 292 年（263 毫微秒）的连续调用的不同点在于：由于数字溢出，
	 * 将无法准确计算已过的时间。
	 */
	// 例如，测试某些代码执行的时间长度：
	// long startTime = System.nanoTime();
	// //... the code being measured ...
	// long estimatedTime = System.nanoTime() - startTime;
	//
	public static long nanoTime() {
		return System.nanoTime();
	}

	/**
	 * @return 把毫秒时间转换成小时分钟秒格式 HH:mm:ss
	 */
	public static String toHHmmss(final long millisecond) {
		long h = millisecond / _HH;
		// int m = (int) ((millisecond - h * _HH) / _MM);
		// int s = (int) ((millisecond - h * _HH - m * _MM) / _SS);
		SimpleDateFormat sdf = new SimpleDateFormat(":mm:ss");
		return h + sdf.format(millisecond);
	}

	/**
	 * @return 把毫秒时间转换成小时分钟秒毫秒格式 HH:mm:ss:SSS
	 */
	public static String toHHmmssSSS(final long millisecond) {
		long h = millisecond / _HH;
		// int m = (int) ((millisecond - h * _HH) / _MM);
		// int s = (int) ((millisecond - h * _HH - m * _MM) / _SS);
		// int ms = (int) (millisecond - h * _HH - m * _MM - s * _SS);
		SimpleDateFormat sdf = new SimpleDateFormat(":mm:ss:SSS");
		return h + sdf.format(millisecond);
	}

	public static void main(String[] args) {
		// new MyTimeSetting().result();
		System.out.println("今天是:" + DateTime.currentDate(DateTime.DateFormat1));
		System.out.println("时间是：" + DateTime.currentTime(DateTime.TimeFormat1));
		System.out.println("现在是："
				+ DateTime.currentDateTime(DateTime.DateTimeFormat1));
		long l = DateTime.currentDateTimeGreenwich(DateTime.DateTimeFormat1);
		System.out.println("格林威治毫秒是:" + l);

		System.out.println("距离格林威治时间：" + DateTime.toHHmmss(l));

		System.out.println(System.currentTimeMillis());
		System.out.println(System.nanoTime());
	}
}

/** -----------------------------分隔线--------------------------------- */
/**
 * 项目中要求 获取java.sql.Timestamp 类型 中的时、分、秒、日期，然后进行比较。 比如 2011-09-21 08:30:00
 * 我要获取里面的 8点30分 然后在程序中判断。 String m= 8:30-9:30之间则设置A 9:30-10:00则设置为B
 * 10:00-10:30则设置为C 10:30-11:00之间则设置D 11:00-11:30则设置为E 11:30-12:30则设置为F
 */
class MyTimeSetting {
	public final String sBegin = "2011-09-21 08:30:00";
	public final String test = "2011-09-21 09:33:00";
	public String state = "";

	public void result() {
		long lBegin = DateTime.dateTimeParse(sBegin, DateTime.DateTimeFormat1);
		long lTest = DateTime.dateTimeParse(test, DateTime.DateTimeFormat1);
		int choice = (int) ((lTest - lBegin) / DateTime._HH);
		switch (choice) {
		case 0:
			state = "A";
			break;
		case 1:
			state = "B";
			break;
		case 2:
			state = "C";
			break;
		case 3:
			state = "D";
			break;
		case 4:
			state = "E";
			break;
		case 5:
			state = "F";
			break;
		default:
			state = "error";
		}
		System.out.println(test + " --- " + state);
	}
}
